from PySide2.QtCore import QSettings, Qt, QTimer, QRect, QPoint, QPropertyAnimation, QEvent, QByteArray
from PySide2.QtWidgets import QWidget, QMenu, QSystemTrayIcon, QApplication, QDialog
from PySide2.QtGui import QIcon, QPaintEvent, QPainter, QBrush, QPen, QColor, QMouseEvent, QContextMenuEvent, \
    QEnterEvent, QFont, QShowEvent

from Helper.GetSystemUseInfo import GetSystemUseInfo
from UI.changecolordialog import ChangeColorDialog
from UI.otherusewidget import OtherUseWidget
from UI.taskusewidget import TaskUseWidget
from UI.aboutdialog import AboutDialog
from UI.ui_uiwidget import Ui_UIWidget
import Resources

import platform


class UIWidget(QWidget):

    def __init__(self, obj: QWidget = None) -> None:
        super(UIWidget, self).__init__(obj)

        self.ui = Ui_UIWidget()
        self.ui.setupUi(self)

        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setContextMenuPolicy(Qt.DefaultContextMenu)

        self.__DefineData()
        self.__InitData()
        self.__InitStyle()
        self.__InitSignalAndSlot()

    def paintEvent(self, event: QPaintEvent) -> None:
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setBrush(QBrush(ChangeColorDialog.Color))
        painter.setPen(QPen(Qt.transparent))
        painter.drawRoundedRect(self.rect(), 6, 6)

    def showEvent(self, event: QShowEvent) -> None:

        if self.ExpendUIAction.isChecked():
            self.ExpendUI()

        # self.slotSetShowTask(self.ShowTaskAction.isChecked())

    def mousePressEvent(self, event: QMouseEvent) -> None:
        super().mousePressEvent(event)
        self.StartDragPoint = event.globalPos() - self.frameGeometry().topLeft()

    def mouseReleaseEvent(self, event: QMouseEvent) -> None:
        super().mouseReleaseEvent(event)
        self.HandleUIPostion()

        if self.isExpendUI and event.button() == Qt.LeftButton:
            self.ExpendUI()

    def mouseMoveEvent(self, event: QMouseEvent) -> None:
        super().mouseMoveEvent(event)

        self.OtherUseWgt.hide()
        self.move(event.globalPos() - self.StartDragPoint)
        self.Settings.setValue("Global/Size", self.geometry())

    def enterEvent(self, event: QEnterEvent) -> None:
        super().enterEvent(event)
        if not self.isExpendUI:
            self.ExpendUI()

    def leaveEvent(self, event: QEvent) -> None:
        super().leaveEvent(event)
        if not self.isExpendUI:
            self.OtherUseWgt.hide()

    def contextMenuEvent(self, event: QContextMenuEvent) -> None:
        super().contextMenuEvent(event)
        self.TrayMenu.move(self.mapToGlobal(event.pos()))
        self.TrayMenu.show()

    # 声明变量
    def __DefineData(self):
        self.Settings = QSettings(self)

        # 菜单和设置子菜单
        self.TrayMenu = QMenu()
        self.SettingsMenu = QMenu()

        self.timer = QTimer(self)
        self.StartDragPoint = QPoint()

        self.SysInfo = GetSystemUseInfo()
        self.InfoDialog = AboutDialog(self)
        self.TaskWidget = TaskUseWidget(self)
        self.OtherUseWgt = OtherUseWidget(self)
        self.SetColorDialog = ChangeColorDialog(self)
        self.Animation = QPropertyAnimation(self.OtherUseWgt, QByteArray(bytearray("geometry", "utf-8")))

        # UI的几何属性
        self.ScreenRect = QApplication.primaryScreen().geometry()

        self.isExpendUI = False

    def __InitData(self):

        self.setGeometry(self.Settings.value("Global/Size", self.geometry()))
        ChangeColorDialog.Color = self.Settings.value("Global/UIColor", QColor(200, 230, 255, 220))

        self.isExpendUI = self.Settings.value("Global/IsExpendUI", False, bool)

        self.HandleUIPostion()

        self.timer.start(1000)

        self.OtherUseWgt.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint)
        self.Animation.setDuration(200)

        # 设置子菜单
        self.SettingsMenu.setIcon(QIcon(":/Image/Setting.png"))
        self.SettingsMenu.setTitle(self.tr("Settings"))

        # 添加菜单项
        self.SetTopAction = self.SettingsMenu.addAction(self.tr("Top"))
        self.AutoStartAction = self.SettingsMenu.addAction(self.tr("AutoStart"))
        self.ShowTaskAction = self.SettingsMenu.addAction(self.tr("ShowTasl"))
        self.ExpendUIAction = self.SettingsMenu.addAction(self.tr("EnpendUI"))

        # 设置菜单项属性
        self.SetTopAction.setCheckable(True)
        self.SetTopAction.setChecked(True)
        self.AutoStartAction.setCheckable(True)
        self.AutoStartAction.setChecked(self.Settings.value("Global/AutoStart", False, bool))
        self.ShowTaskAction.setCheckable(True)
        self.ShowTaskAction.setChecked(self.Settings.value("Global/ShowTask", False, bool))
        self.ExpendUIAction.setCheckable(True)
        self.ExpendUIAction.setChecked(self.Settings.value("Global/IsExpendUI", False, bool))

        # 右键菜单
        self.HidenAction = self.TrayMenu.addAction(QIcon(":/Image/Show.png"), self.tr("Hiden"))
        self.RefreshAction = self.TrayMenu.addAction(QIcon(":/Image/Refresh.png"), self.tr("Refresh"))
        self.ColorAction = self.TrayMenu.addAction(QIcon(":/Image/Color.png"), self.tr("Color"))
        self.InfoAction = self.TrayMenu.addAction(QIcon(":/Image/Info.png"), self.tr("Info"))
        self.TrayMenu.addMenu(self.SettingsMenu)
        self.ExitAction = self.TrayMenu.addAction(QIcon(":/Image/Exit.png"), self.tr("Exit"))

        if self.Settings.value("Global/ShowUI", False, bool):
            self.toShow()
        else:
            self.toHiden()

        self.slotSetShowTask(self.ShowTaskAction.isChecked())

    def __InitStyle(self):
        MenuStyleStr = str("QMenu {background-color:rgba(255,255,255,0.9);padding:5px;border-radius: 5px;}\
                                QMenu::item {min-width:50px;padding:5px;margin:1px;border-radius: 3px;}\
                                QMenu::item:selected {background:rgba(210,235,255,1);border-radius: 3px;}\
                                QMenu::item:pressed {background:rgba(210,235,255,0.5);border:1px solid rgba(82,130,164,1);border-radius: 3px;}")

        self.SettingsMenu.setFont(QFont("Sim-Sun", 9, QFont.Normal, False))
        self.TrayMenu.setFont(QFont("Sim-Sun", 9, QFont.Normal, False))

        self.SettingsMenu.setWindowFlag(Qt.FramelessWindowHint)
        self.SettingsMenu.setAttribute(Qt.WA_TranslucentBackground)
        self.SettingsMenu.setStyleSheet(MenuStyleStr)

        self.TrayMenu.setWindowFlag(Qt.FramelessWindowHint)
        self.TrayMenu.setAttribute(Qt.WA_TranslucentBackground)
        self.TrayMenu.setStyleSheet(MenuStyleStr)

    def __InitSignalAndSlot(self):

        # 按钮信号槽链接

        # 按钮信号槽链接
        self.SetTopAction.toggled.connect(self.SetWindowTop)
        self.HidenAction.triggered.connect(self.slotHidenShow)
        self.RefreshAction.triggered.connect(lambda: self.slotTimeOut())
        self.ExitAction.triggered.connect(lambda: QApplication.quit())
        self.ColorAction.triggered.connect(self.slotSetUIColor)
        self.InfoAction.triggered.connect(lambda: self.InfoDialog.show())
        self.timer.timeout.connect(self.slotTimeOut)
        self.SetColorDialog.signalColorChanged.connect(lambda: self.update())
        self.SetColorDialog.signalColorChanged.connect(lambda: self.OtherUseWgt.update())

        self.ExpendUIAction.toggled.connect(self.slotIsExpendUI)
        self.ShowTaskAction.toggled.connect(self.slotSetShowTask)

        self.AutoStartAction.toggled.connect(self.slotSetAutoRun)

        # 界面间信号槽链接
        self.TaskWidget.signalHomeUIControl.connect(self.slotHidenShow)

    def slotTimeOut(self):
        NetsentValue = self.SysInfo.GetNetSent()
        NetRecValue = self.SysInfo.GetNetRec()

        NetSentValueStr = self.HandleNetValue(NetsentValue)
        NetRecValueStr = self.HandleNetValue(NetRecValue)

        CPUInfo = self.SysInfo.GetCPUInfo()
        MemoryInfo = self.SysInfo.GetMemoryInfo()

        self.ui.label_NetSentValue.setText(NetSentValueStr)
        self.ui.label_NetRecValue.setText(NetRecValueStr)

        self.OtherUseWgt.SetCPUUseValue(CPUInfo)
        self.OtherUseWgt.SetMemUseValue(MemoryInfo)

        self.TaskWidget.updateRect()
        self.TaskWidget.SetNetSentValue(NetSentValueStr)
        self.TaskWidget.SetNetRecValue(NetRecValueStr)
        self.TaskWidget.SetCPUUseValue(CPUInfo)
        self.TaskWidget.SetMemUseValue(MemoryInfo)

    def slotHidenShow(self):
        self.toShow() if self.isHidden() == True else self.toHiden()

    def slotClickedTray(self, reason: QSystemTrayIcon.ActivationReason):
        if ((reason != QSystemTrayIcon.Context) and (not self.isHidden())):
        # if reason != QSystemTrayIcon.Context:
            self.toShow()

    def slotSetAutoRun(self, start: bool):

        if (platform.system() == "Windows"):
            AUTO_RUN = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
            AppName = QApplication.applicationName()
            AppPath = QApplication.applicationFilePath()
            RegSettings = QSettings(AUTO_RUN, QSettings.NativeFormat)

            if (start):
                RegSettings.setValue(AppName, AppPath.replace("/", "\\"))
                self.Settings.setValue("Global/AutoStart", True)
            else:
                RegSettings.remove(AppName)
                self.Settings.setValue("Global/AutoStart", False)
        else:
            pass

    def slotSetUIColor(self):

        if self.SetColorDialog.exec_() == QDialog.DialogCode.Accepted:
            self.Settings.setValue("Global/UIColor", ChangeColorDialog.Color)
        else:
            pass

    def slotIsExpendUI(self, expend: bool):
        self.isExpendUI = expend
        self.Settings.setValue("Global/IsExpendUI", self.isExpendUI)



        if self.isExpendUI and not self.isHidden():
            self.ExpendUI()
        else:
            self.OtherUseWgt.hide()

    def slotSetShowTask(self, show: bool):
        self.Settings.setValue("Global/ShowTask", show)
        if show:
            self.TaskWidget.show()
        else:
            self.TaskWidget.hide()

    def HandleUIPostion(self):
        Geometry = self.geometry()
        if (Geometry.top() < 0):
            Geometry.setTop(0)
        if (Geometry.left() < 0):
            Geometry.setLeft(0)
        if (Geometry.right() > self.ScreenRect.right()):
            Geometry.setLeft(self.ScreenRect.right() - Geometry.width())
        if (Geometry.bottom() > self.ScreenRect.bottom()):
            Geometry.setTop(self.ScreenRect.bottom() - Geometry.height())

        self.setGeometry(Geometry)
        self.Settings.setValue("Global/Size", self.geometry())

    def HandleNetValue(self, InValue: float) -> str:
        retValue = ""
        if ((InValue / 1024) >= 1024):
            retValue = f"{(InValue / (1024 * 1024)):.2f}" + "M/s"
        else:
            retValue = f"{(InValue / 1024):.2f}" + "K/s"

        return retValue

    def SetWindowTop(self, isTop: bool):
        hidened = self.isHidden()
        if (isTop):
            self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint)
        else:
            self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint)

        self.toHiden() if hidened == True else self.toShow()

    def ExpendUI(self):
        self.OtherUseWgt.show()
        framGeo = self.geometry()
        self.Animation.setStartValue(
            QRect(framGeo.left() + 1, framGeo.bottom() - 30, framGeo.width() - 2, framGeo.height()))
        self.Animation.setEndValue(
            QRect(framGeo.left() + 1, framGeo.bottom(), framGeo.width() - 2, framGeo.height()))
        self.Animation.start()

    def toHiden(self):
        self.hide()
        self.OtherUseWgt.hide()
        self.HidenAction.setText(self.tr("Show"))
        self.Settings.setValue("Global/ShowUI", False)

    def toShow(self):
        self.show()
        self.raise_()
        self.HidenAction.setText(self.tr("Hiden"))
        self.Settings.setValue("Global/ShowUI", True)

    UIColor = QColor()
